package com.xdf.xzymanagementsystem.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StringUtils {
    private static final char SEPARATOR = '_';
    private static final String CHARSET_NAME = "UTF-8";
    public static final String HASH_ALGORITHM = "SHA-1";
    public static final int HASH_INTERATIONS = 1024;
    public static final int SALT_SIZE = 8;
    public static final String EMPTY = "";
    public static final String REGEX_CHINESE = "[\u4e00-\u9fa5]";// 中文的正则表达式

    /**
     * 1. 将NULL返回空字符串
     * 2. 将"NULL","null"返回空字符串
     * 3. 其他情况返回原始字符串
     * @param o
     * @return
     */
    public static String filterNull(Object o) {
        return o != null && !"null".equals(o.toString()) ? o.toString().trim() : "" ;
    }

    /**
     * 是否是空字符串
     * @param o
     * @return
     */
    public static boolean isEmpty(Object o) {
        if (o == null) {
            return true;
        }
        if ("".equals(filterNull(o.toString()))) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 是否非空字符串
     * @param o
     * @return
     */
    public static boolean isNotEmpty(Object o) {
        if (o == null) {
            return false;
        }
        if ("".equals(filterNull(o.toString()))) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 是否可转化为数字
     * @param o
     * @return
     */
    public static boolean isNum(Object o) {
        try {
            new BigDecimal(o.toString());
            return true;
        } catch (Exception e) {
        }
        return false;
    }

    /**
     * 是否可转化为Long型数字
     * @param o
     * @return
     */
    public static boolean isLong(Object o) {
        try {
            new Long(o.toString());
            return true;
        } catch (Exception e) {
        }
        return false;
    }

    /**
     * 转化为Long型数字, 不可转化时返回0
     * @param o
     * @return
     */
    public static Long toLong(Object o) {
        if (isLong(o)) {
            return new Long(o.toString());
        } else {
            return 0L;
        }
    }

    /**
     * 转化为int型数字, 不可转化时返回0
     * @param o
     * @return
     */
    public static int toInt(Object o) {
        if (isNum(o)) {
            return new Integer(o.toString());
        } else {
            return 0;
        }
    }

    /**
     * 按字符从左截取固定长度字符串, 防止字符串超长, 默认截取50
     * @param o
     * @return
     */
    public static String holdmaxlength(Object o) {
        int maxlength = 50;
        if (o == null) {
            return "";
        }
        return subStringByByte(o, maxlength);
    }

    /**
     * 从左截取固定长度字符串, 防止字符串超长, maxlength为0时默认50
     * @param o
     * @return
     */
    public static String holdmaxlength(Object o, int maxlength) {
        maxlength = maxlength <= 0 ? 50 : maxlength;
        if (o == null) {
            return "";
        }
        return subStringByByte(o, maxlength);
    }

    /**
     * 按字节截取字符串
     * @param o
     * @param len
     * @return
     */
    private static String subStringByByte(Object o, int len) {
        if (o == null) {
            return "";
        }
        String str = o.toString();
        String result = null;
        if (str != null) {
            byte[] a = str.getBytes();
            if (a.length <= len) {
                result = str;
            } else if (len > 0) {
                result = new String(a, 0, len);
                int length = result.length();
                if (str.charAt(length - 1) != result.charAt(length - 1)) {
                    if (length < 2) {
                        result = null;
                    } else {
                        result = result.substring(0, length - 1);
                    }
                }
            }
        }
        return result;
    }

    /**
     * 逗号表达式_添加
     * @param commaexpress 原逗号表达式 如 A,B
     * @param newelement   新增元素 C
     * @return A,B,C
     */
    public static String comma_add(String commaexpress, String newelement) {
        return comma_rect(filterNull(commaexpress) + "," + filterNull(newelement));
    }

    /**
     * 逗号表达式_删除
     * @param commaexpress  原逗号表达式 如 A,B,C
     * @param delelement 删除元素 C,A
     * @return B
     */
    public static String comma_del(String commaexpress, String delelement) {
        if ((commaexpress == null) || (delelement == null) || (commaexpress.trim().equals(delelement.trim()))) {
            return "";
        }
        String[] deletelist = delelement.split(",");
        String result = commaexpress;
        for (String delstr : deletelist) {
            result = comma_delone(result, delstr);
        }
        return result;
    }

    /**
     * 逗号表达式_单一删除
     * @param commaexpress  原逗号表达式 如 A,B,C
     * @param delelement 删除元素 C
     * @return A,B
     */
    public static String comma_delone(String commaexpress, String delelement) {
        if ((commaexpress == null) || (delelement == null) || (commaexpress.trim().equals(delelement.trim()))) {
            return "";
        }
        String[] strlist = commaexpress.split(",");
        StringBuffer result = new StringBuffer();
        for (String str : strlist) {
            if ((!str.trim().equals(delelement.trim())) && (!"".equals(str.trim()))) {
                result.append(str.trim() + ",");
            }
        }
        return result.toString().substring(0, result.length() - 1 > 0 ? result.length() - 1 : 0);
    }

    /**
     * 逗号表达式_判断是否包含元素
     * @param commaexpress 逗号表达式 A,B,C
     * @param element C
     * @return true
     */
    public static boolean comma_contains(String commaexpress, String element) {
        boolean flag = false;
        commaexpress = filterNull(commaexpress);
        element = filterNull(element);
        if (!"".equals(commaexpress) && !"".equals(element)) {
            String[] strlist = commaexpress.split(",");
            for (String str : strlist) {
                if (str.trim().equals(element.trim())) {
                    flag = true;
                    break;
                }
            }
        }
        return flag;
    }

    /**
     * 逗号表达式_取交集
     * @param commaexpressA 逗号表达式1  A,B,C
     * @param commaexpressB 逗号表达式2  B,C,D
     * @return B,C
     */
    public static String comma_intersect(String commaexpressA, String commaexpressB) {
        commaexpressA = filterNull(commaexpressA);
        commaexpressB = filterNull(commaexpressB);
        StringBuffer result = new StringBuffer();
        String[] strlistA = commaexpressA.split(",");
        String[] strlistB = commaexpressB.split(",");
        for (String boA : strlistA) {
            for (String boB : strlistB) {
                if (boA.trim().equals(boB.trim())) {
                    result.append(boA.trim() + ",");
                }
            }
        }
        return comma_rect(result.toString());
    }

    /**
     * 逗号表达式_规范
     * @param commaexpress  逗号表达式  ,A,B,B,,C
     * @return A,B,C
     */
    public static String comma_rect(String commaexpress) {
        commaexpress = filterNull(commaexpress);
        String[] strlist = commaexpress.split(",");
        StringBuffer result = new StringBuffer();
        for (String str : strlist) {
            if (!("".equals(str.trim())) && !("," + result.toString() + ",").contains("," + str + ",") && !"null".equals(str)) {
                result.append(str.trim() + ",");
            }
        }
        return result.toString().substring(0, (result.length() - 1 > 0) ? result.length() - 1 : 0);
    }

    /**
     * 逗号表达式_反转
     * @param commaexpress A,B,C
     * @return C,B,A
     */
    public static String comma_reverse(String commaexpress) {
        commaexpress = filterNull(commaexpress);
        String[] ids = commaexpress.split(",");
        StringBuffer str = new StringBuffer();
        for (int i = ids.length - 1; i >= 0; i--) {
            str.append(ids[i] + ",");
        }
        return comma_rect(str.toString());
    }

    /**
     * 逗号表达式_获取首对象
     * @param commaexpress A,B,C
     * @return A
     */
    public static String comma_first(String commaexpress) {
        commaexpress = filterNull(commaexpress);
        String[] ids = commaexpress.split(",");
        System.out.println("length:" + ids.length);
        if ((ids != null) && (ids.length > 0)) {
            return ids[0];
        }
        return null;
    }

    /**
     * 逗号表达式_获取尾对象
     * @param commaexpress A,B,C
     * @return C
     */
    public static String comma_last(String commaexpress) {
        commaexpress = filterNull(commaexpress);
        String[] ids = commaexpress.split(",");
        if ((ids != null) && (ids.length > 0)) {
            return ids[(ids.length - 1)];
        }
        return null;
    }

    /**
     * 替换字符串,支持字符串为空的情形
     * @param strData
     * @param regex
     * @param replacement
     * @return
     */
    public static String replace(String strData, String regex, String replacement) {
        return strData == null ? "" : strData.replaceAll(regex, replacement);
    }

    /**
     * 字符串转为HTML显示字符
     * @param strData
     * @return
     */
    public static String String2HTML(String strData){
        if( strData == null || "".equals(strData) ){
            return "" ;
        }
        strData = replace(strData, "&", "&amp;");
        strData = replace(strData, "<", "&lt;");
        strData = replace(strData, ">", "&gt;");
        strData = replace(strData, "\"", "&quot;");
        return strData;
    }

    /**     * 把异常信息转换成字符串，以方便保存 */
    public static String getexceptionInfo(Exception e){
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try{
            e.printStackTrace(new PrintStream(baos));
        }finally{
            try {
                baos.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
        return baos.toString();
    }

    /** 过滤特殊符号 */
    public static String regex(String str){
        Pattern pattern = Pattern.compile("[0-9-:/ ]");// 中文汉字编码区间
        Matcher matcher;
        char[] array = str.toCharArray();
        for (int i = 0; i < array.length; i++) {
            matcher = pattern.matcher(String.valueOf(array[i]));
            if (!matcher.matches()) {// 空格暂不替换
                str = str.replace(String.valueOf(array[i]), "");// 特殊字符用空字符串替换
            }
        }

        return str;
    }

    public static String comma_insert(String commaexpress, String newelement,int index){
        int length = commaexpress.length();
        if ( index > length ) {
            index = length;
        }else if ( index < 0){
            index = 0;
        }
        String result = commaexpress.substring(0, index) + newelement + commaexpress.substring(index, commaexpress.length());
        return result;
    }

    /**
     * 将"/"替换成"\"
     * @param strDir
     * @return
     */
    public static String changeDirection(String strDir) {
        String s = "/";
        String a = "\\";
        if (strDir != null && !" ".equals(strDir)) {
            if (strDir.contains(s)) {
                strDir = strDir.replace(s, a);
            }
        }
        return strDir;
    }

    /**
     * 去除字符串中 头和尾的空格，中间的空格保留
     *
     * @Title: trim
     * @Description: TODO
     * @return String
     * @throws
     */
    public static String trim(String s) {
        int i = s.length();// 字符串最后一个字符的位置
        int j = 0;// 字符串第一个字符
        int k = 0;// 中间变量
        char[] arrayOfChar = s.toCharArray();// 将字符串转换成字符数组
        while ((j < i) && (arrayOfChar[(k + j)] <= ' '))
            ++j;// 确定字符串前面的空格数
        while ((j < i) && (arrayOfChar[(k + i - 1)] <= ' '))
            --i;// 确定字符串后面的空格数
        return (((j > 0) || (i < s.length())) ? s.substring(j, i) : s);// 返回去除空格后的字符串
    }
    /**
     * 得到大括号中的内容
     * @param str
     * @return
     */
    public static String getBrackets(String str) {
        int a = str.indexOf("{");
        int c = str.indexOf("}");
        if (a >= 0 && c >= 0 & c > a) {
            return (str.substring(a + 1, c));
        } else {
            return str;
        }
    }

    /**
     * 将字符串中所有的，替换成|
     *
     * @param str
     * @return
     */
    public static String commaToVerti(String str) {
        if (str != null && !"".equals(str) && str.contains(",")) {
            return str.replaceAll(",", "|");
        } else {
            return str;
        }
    }

    /**
     * 去掉字符串中、前、后的空格
     * @param name
     * @throws IOException
     */
    public static String extractBlank(String name) {
        if (name != null && !"".equals(name)) {
            return name.replaceAll(" +", "");
        } else {
            return name;
        }
    }

    /**
     * 将null换成""
     * @param str
     * @return
     */
    public static String ConvertStr(String str) {
        return str != null && !"null".equals(str) ? str.trim() : "";
    }

    public static String fillToLength(String ori,int length,String filler,boolean fillAtLeft){
        if( length<=ori.length() ) return ori;// 如果指定的长度小于字符串原始长度，那么返回原始字符串
        if( filterNull(filler).length()<=0 ) return ori;// 没有设置填充物则返回原始字符串
        int diff = length - ori.length();

        StringBuilder sb = new StringBuilder();
        String result = "";
        for(int i=0;i<diff;i++){
            sb.append(filler);
        }

        if( fillAtLeft == true ){
            result = sb.toString() + ori;
        }else{
            result = ori + sb.toString();
        }

        return result;
    }

    /**
     * 填充字符串长度到2，不足补充0
     * @param ori
     * @return
     */
    public static String fillLength2(String ori){
        return fillToLength(ori,2,"0",true);
    }


    /**
     * 2021年8月2日 14:23:51 追加下面的方法
     */

    /**
     * 将字符串转换为字节数组
     * @param str
     * @return
     */
    public static byte[] getBytes(String str) {
        if (str != null) {
            try {
                return str.getBytes(CHARSET_NAME);
            } catch (UnsupportedEncodingException e) {
                return null;
            }
        } else {
            return null;
        }
    }

    /**
     * 将字节数组转换为字符串
     * @param bytes
     * @return
     */
    public static String toString(byte[] bytes) {
        try {
            return new String(bytes, CHARSET_NAME);
        } catch (UnsupportedEncodingException e) {
            return EMPTY;
        }
    }

    /**
     * 驼峰命名法工具
     *
     * @return toCamelCase("hello_world") == "helloWorld"
     *         toCapitalizeCamelCase("hello_world") == "HelloWorld"
     *         toUnderScoreCase("helloWorld") = "hello_world"
     */
    public static String toCamelCase(String s) {
        if (s == null) {
            return null;
        }

        s = s.toLowerCase();

        StringBuilder sb = new StringBuilder(s.length());
        boolean upperCase = false;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);

            if (c == SEPARATOR) {
                upperCase = true;
            } else if (upperCase) {
                sb.append(Character.toUpperCase(c));
                upperCase = false;
            } else {
                sb.append(c);
            }
        }

        return sb.toString();
    }

    /**
     * 驼峰命名法工具
     *
     * @return toCamelCase("hello_world") == "helloWorld"
     *         toCapitalizeCamelCase("hello_world") == "HelloWorld"
     *         toUnderScoreCase("helloWorld") = "hello_world"
     */
    public static String toCapitalizeCamelCase(String s) {
        if (s == null) {
            return null;
        }
        s = toCamelCase(s);
        return s.substring(0, 1).toUpperCase() + s.substring(1);
    }

    /**
     * 驼峰命名法工具
     *
     * @return toCamelCase("hello_world") == "helloWorld"
     *         toCapitalizeCamelCase("hello_world") == "HelloWorld"
     *         toUnderScoreCase("helloWorld") = "hello_world"
     */
    public static String toUnderScoreCase(String s) {
        if (s == null) {
            return null;
        }

        StringBuilder sb = new StringBuilder();
        boolean upperCase = false;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);

            boolean nextUpperCase = true;

            if (i < (s.length() - 1)) {
                nextUpperCase = Character.isUpperCase(s.charAt(i + 1));
            }

            if ((i > 0) && Character.isUpperCase(c)) {
                if (!upperCase || !nextUpperCase) {
                    sb.append(SEPARATOR);
                }
                upperCase = true;
            } else {
                upperCase = false;
            }

            sb.append(Character.toLowerCase(c));
        }

        return sb.toString();
    }

    /**
     *
     * <p>
     * 判断字符串是否为空. 为空条件:全角\半角\tab 等没有实际意义的字符.
     * 具体参看{@link Character#isWhitespace(char)}对空格的定义.
     * </p>
     *
     * <pre>
     * StringUtils.isBlank("  ") = true 为半角空格
     * StringUtils.isBlank("　　") = true 为全角空格
     * StringUtils.isBlank("	") = true 为tab键
     * </pre>
     *
     * @param str
     *            字符串
     * @return <code>true<code> 字符串为空 ,<code>false</code> 不为空
     */
    public static boolean strIsBlank(String str) {
        int strLen;
        if (str == null || (strLen = str.length()) == 0) {
            return true;
        }
        for (int i = 0; i < strLen; i++) {
            if ((Character.isWhitespace(str.charAt(i)) == false)) {
                return false;
            }
        }
        return true;
    }


    /**
     * 排除非数字的字符，返回 Integer 类型数据
     * 如果出现异常则返回默认值
     * @param text
     * @param defaultValue
     * @return
     */
    public static Integer abnormalTextToInt(String text, Integer defaultValue) {
        try {
            return Integer.parseInt(Pattern.compile("[^0-9]").matcher(text).replaceAll("").trim());
        } catch (Exception e) {
            return defaultValue;
        }
    }


    /**
     * 排除没有意义的特殊符号：回车符、换行符、Tab 制表符
     * 同时删除头尾的空格符，中间的不删除
     * @param str
     * @return
     */
    public static String removeNoSentido(String str) {
        String dest = "";
        if (str != null) {
            // 如果要同时排除：回车、换行、制表、空格符号，则：
            // Pattern p = Pattern.compile("\\s*|\t|\r|\n")
            Pattern p = Pattern.compile("\\t|\r|\n");
            Matcher m = p.matcher(str);
            dest = m.replaceAll("");
        }
        return trim(dest);
    }

    /**
     * 移除字符串中所有：回车符、换行符、制表符、空格符
     * @param str
     * @return
     */
    public static String removeNoSentidoAndBlank(String str) {
        String dest = "";
        if (str != null) {
            // 如果要同时排除：回车、换行、制表、空格符号，则：
            Pattern p = Pattern.compile("\\s*|\t|\r|\n");
            Matcher m = p.matcher(str);
            dest = m.replaceAll("");
        }
        return dest;
    }

    /**
     * 排除字符串中的中文，返回其他部分构成的字符串
     * @param str
     * @return
     */
    public static String removeChinese(String str){
        Pattern pat = Pattern.compile(REGEX_CHINESE);
        Matcher mat = pat.matcher(str);
        return mat.replaceAll("");
    }

    public static String removeNumbers(String str){
        Pattern pat = Pattern.compile("[0-9]");
        Matcher mat = pat.matcher(str);
        return mat.replaceAll("");
    }

    public static String removeEnglish(String str){
        Pattern pat = Pattern.compile("[a-zA-Z]");
        Matcher mat = pat.matcher(str);
        return mat.replaceAll("");
    }

    /**
     * 排除特殊符号、空格符、中文、数字
     * 返回英文字符并包含可见符号
     * @param str
     * @return
     */
    public static String getEnglish(String str){
        str = removeNoSentidoAndBlank(str);// 移除所有特殊符号和空格
        str = removeChinese(str);// 移除中文
        str = removeNumbers(str);// 移除数字
        return str;
    }

    /**
     * 返回的数字字符串包含可见符号
     * @param str
     * @return
     */
    public static String getNumbers(String str){
        str = removeNoSentidoAndBlank(str);// 移除所有特殊符号和空格
        str = removeChinese(str);// 移除中文
        str = removeEnglish(str);// 移除英文字母
        return str;
    }

    public static void main(String[] args) {
        System.out.println(removeEnglish("a12A34Z"));
    }

    // 获取排除后缀名后的纯文件名
    public static String getFileNameNoSuffix(String fileNameWithSuffix){
        if( fileNameWithSuffix == null || fileNameWithSuffix.length()<=0 ) return "";
        int dotIndex = fileNameWithSuffix.lastIndexOf(".");
        if( dotIndex == -1) return fileNameWithSuffix;
        return fileNameWithSuffix.substring(0,dotIndex);
    }

    // 获取文件后缀名
    public static String getFileSuffix(String fileNameWithSuffix){
        if( fileNameWithSuffix == null || fileNameWithSuffix.length()<=0 ) return "";
        int dotIndex = fileNameWithSuffix.lastIndexOf(".");
        if( dotIndex == -1) return "";
        return fileNameWithSuffix.substring(dotIndex+1);
    }

    public static String getExtension(String str) {
        if(str == null) return null;
        int i = str.lastIndexOf('.');
        if(i >= 0) {
            return str.substring(i+1);
        }
        return null;
    }

    /**
     * 根据正则表达式获取 input 中匹配的多个结果
     * @param input 字符串变量
     * @param regex 正则表达式
     * @return 字符串集合 - List<String>
     */
    public static List<String> getRegexResultMult(String input, String regex){
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(input);

        List<String> ret = new ArrayList<>();
        while (matcher.find()) {
            String match = matcher.group(0);
            ret.add(match);
        }
        return ret;
    }
}
